// DumpTCPPayloadView.cpp : implementation of the CDumpTCPPayloadView class
//

#include "stdafx.h"
#include "DumpTCPPayload.h"
#include <vector>
#include "DumpTCPPayloadDoc.h"
#include "DumpTCPPayloadView.h"
#include "MyNetworkAnalyzer.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CDumpTCPPayloadView

IMPLEMENT_DYNCREATE(CDumpTCPPayloadView, CListView)

BEGIN_MESSAGE_MAP(CDumpTCPPayloadView, CListView)
END_MESSAGE_MAP()

// CDumpTCPPayloadView construction/destruction

CDumpTCPPayloadView::CDumpTCPPayloadView()
{
	// TODO: add construction code here

}

CDumpTCPPayloadView::~CDumpTCPPayloadView()
{
}

BOOL CDumpTCPPayloadView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs
	cs.style |= LVS_REPORT;
	return CListView::PreCreateWindow(cs);
}

TCHAR* FormatData( CDumpInfo* info)
{
	const TCHAR ctszHex[20]={_T("0123456789abcdef.-+")};	
	static TCHAR szHexString[4096]={0};
	ZeroMemory( szHexString, 4096* sizeof( TCHAR) );
	int idx=0;
	char l,h;
	for(int i=0;i< min( info->dataLengh,1024) ; i++)
	{
		h = (info->data[i] >> 4) & 0x0f;
		ASSERT( h>=0 && h<= 0xf );

		szHexString[idx++]= ctszHex[ h ];
		l = info->data[i] & 0x0f;
		ASSERT( l>=0 && l<= 0xf );

		szHexString[idx++]= ctszHex[ l ];
		szHexString[idx++]=(_T(' ') );
	}
	if( info->dataLengh > 1024 )
	{
		szHexString[idx++] = _T('.');
		szHexString[idx++] = _T('.');
	}
	szHexString[idx++] = 0;

	return szHexString;
}

TCHAR* FormatIPPort(ULONG ip,ULONG port)
{
	static TCHAR text[ 256 ];
	ZeroMemory( text, 256* sizeof( TCHAR ) );
	unsigned char* szIP =(unsigned char*) &ip;
	_stprintf( text, _T("%u.%u.%u.%u:%u"), szIP[3],szIP[2],szIP[1],szIP[0],port);
	return text;
}

void CDumpTCPPayloadView::OnInitialUpdate()
{
	CListView::OnInitialUpdate();


	// TODO: You may populate your ListView with items by directly accessing
	//  its list control through a call to GetListCtrl().

   // this code only works for a report-mode list view
   ASSERT(GetStyle() & LVS_REPORT);

   // Gain a reference to the list control itself
   CListCtrl& theCtrl = GetListCtrl();

   // Insert a column. This override is the most convenient.
   theCtrl.InsertColumn(0, _T("idx"), LVCFMT_LEFT);

   theCtrl.SetExtendedStyle( LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES );

   // The other InsertColumn() override requires an initialized
   // LVCOLUMN structure.
   LVCOLUMN col;
   col.mask = LVCF_FMT | LVCF_TEXT;
   col.pszText = _T("src:port");
   
   col.fmt = LVCFMT_LEFT;
   theCtrl.InsertColumn(1, &col);

   col.pszText = _T("dst:port");
   theCtrl.InsertColumn(2, &col);

   col.pszText = _T("length");
   theCtrl.InsertColumn(3, &col);


   col.pszText = _T("dump");
   theCtrl.InsertColumn(4, &col);

   // Set reasonable widths for our columns
   theCtrl.SetColumnWidth(0, 40);
   theCtrl.SetColumnWidth(1, 200);
   theCtrl.SetColumnWidth(2, 200);
   theCtrl.SetColumnWidth(3, 100);
   theCtrl.SetColumnWidth(4, 1000);

	CString strPathName = GetDocument()->GetPathName();
	CMyCmdline& cmdline = ((CDumpTCPPayloadApp*)AfxGetApp())->m_cmdInfo;
	TDumps&	dumps = GetDocument()->m_dumps;

	MyNetworkAnalyzer*	analyzer = GetDocument()->analyzer;

	//__asm int 3;

	analyzer->Init( strPathName.GetBuffer(),
					cmdline.m_strDisplayFilter.GetBuffer( cmdline.m_strDisplayFilter.GetLength() ),
					cmdline.m_strConversationFilter.GetBuffer( cmdline.m_strConversationFilter.GetLength() ),
					dumps);
	TCHAR szText[16]={0};
	cmdline.m_strDisplayFilter.ReleaseBuffer();
	cmdline.m_strConversationFilter.ReleaseBuffer();
	
	theCtrl.DeleteAllItems();

	int i=0;
	TCHAR szIdx[16]={0};
	TCHAR* pText=NULL;	
	

	for(TDumps::iterator it=dumps.begin(); it != dumps.end();it ++,i++ )
	{
		CDumpInfo* info = *it;
		_itot(i,szIdx,10);
		int c = theCtrl.InsertItem(i, szIdx);
		pText = FormatIPPort(info->srcIP,info->srcPort);
		theCtrl.SetItemText(c,1,pText );
		
		pText = FormatIPPort(info->dstIP,info->dstPort) ;
		theCtrl.SetItemText(c,2,pText);

		_itot( info->dataLengh, szIdx,10);
		theCtrl.SetItemText(c,3,szIdx);

		pText = FormatData(info);
		theCtrl.SetItemText(c,4,pText);
	}
//	f1.Close();

}


// CDumpTCPPayloadView diagnostics

#ifdef _DEBUG
void CDumpTCPPayloadView::AssertValid() const
{
	CListView::AssertValid();
}

void CDumpTCPPayloadView::Dump(CDumpContext& dc) const
{
	CListView::Dump(dc);
}

CDumpTCPPayloadDoc* CDumpTCPPayloadView::GetDocument() const // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CDumpTCPPayloadDoc)));
	return (CDumpTCPPayloadDoc*)m_pDocument;
}
#endif //_DEBUG


// CDumpTCPPayloadView message handlers
void CDumpTCPPayloadView::OnUpdate(CView* /*pSender*/, LPARAM /*lHint*/, CObject* /*pHint*/)
{
	// TODO: Add your specialized code here and/or call the base class

}
